import { readBody, defineEventHandler } from 'h3'
import redis from '../../util/redis'
import { recordLog } from '../../util/log'

// POST /api/live/birthday.save
// body: { key: string, name: string, message: string, expireSeconds?: number }
export default defineEventHandler(async (event) => {
  try {
    const body = await readBody(event) as any
    const key = body?.key ?? ''
    const name = body?.name ?? ''
  const message = body?.message ?? ''
  // optional image as data URL (base64) from client
  const imageBase64 = body?.imageBase64 ?? null
    let expireSeconds = Number(body?.expireSeconds ?? 0)

    if (!key || typeof key !== 'string') {
      event.node.res.statusCode = 400
      return { status: 400, message: 'missing key' }
    }

    // reject Chinese characters in key (require ASCII-friendly key)
    if (/[\u4e00-\u9fff]/.test(key)) {
      event.node.res.statusCode = 400
      return { status: 400, message: 'key must not contain Chinese characters' }
    }

    if (typeof name !== 'string' || name.length === 0) {
      event.node.res.statusCode = 400
      return { status: 400, message: 'missing name' }
    }

    if (typeof message !== 'string' || message.length === 0) {
      event.node.res.statusCode = 400
      return { status: 400, message: 'missing message' }
    }

    // validate image (if provided): must be a base64 data URL or base64 string and <= 1MB
    if (imageBase64 !== null) {
      if (typeof imageBase64 !== 'string' || imageBase64.length === 0) {
        event.node.res.statusCode = 400
        return { status: 400, message: 'invalid image' }
      }
      try {
        // strip data URL prefix if present
        const commaIndex = imageBase64.indexOf(',')
        const b64 = commaIndex >= 0 ? imageBase64.slice(commaIndex + 1) : imageBase64
        const buf = Buffer.from(b64, 'base64')
        const maxBytes = 1 * 1024 * 1024 // 1MB
        if (buf.length > maxBytes) {
          event.node.res.statusCode = 400
          return { status: 400, message: 'image too large (max 1MB)' }
        }
        // Optionally we could validate mime type from prefix, but skip for brevity
      } catch (e) {
        event.node.res.statusCode = 400
        return { status: 400, message: 'invalid base64 image' }
      }
    }

    // Max expire 30 days
    const maxSeconds = 30 * 24 * 3600
    if (!Number.isFinite(expireSeconds) || expireSeconds <= 0) {
      // default 7 days
      expireSeconds = 7 * 24 * 3600
    }
    if (expireSeconds > maxSeconds) expireSeconds = maxSeconds

  const payload = JSON.stringify({ name, message, image: imageBase64, created: new Date().toISOString() })

    try {
      await (redis as any).set(key, payload, 'EX', expireSeconds)
      await recordLog(event as any, { message: `birthday: saved key=${key} expire=${expireSeconds}s`, userId: 0 })
      return { status: 'ok', key, expireSeconds }
    } catch (err: any) {
      event.node.res.statusCode = 500
      await recordLog(event as any, { message: `birthday: redis set failed ${String(err)}`, userId: 0 })
      return { status: 500, message: 'redis set failed', error: String(err) }
    }
  } catch (err: any) {
    event.node.res.statusCode = 500
    await recordLog(event as any, { message: `birthday: internal error ${String(err)}`, userId: 0 })
    return { status: 500, message: 'internal error', error: String(err) }
  }
})
